package com.ruoyi.materialCuttingPlan.service.impl;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

import com.ezylang.evalex.BaseException;
import com.ezylang.evalex.EvaluationException;
import com.ezylang.evalex.Expression;
import com.ezylang.evalex.parser.ParseException;
import com.ruoyi.common.annotation.DataScope;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.materialCuttingPlan.domain.*;
import com.ruoyi.materialCuttingPlan.mapper.McpFormulasMapper;
import com.ruoyi.materialCuttingPlan.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import com.ruoyi.common.utils.StringUtils;
import org.springframework.transaction.annotation.Transactional;
import com.ruoyi.materialCuttingPlan.mapper.McpWindowsMapper;

/**
 * 门窗详细信息Service业务层处理
 * 
 * @author ruoyi
 * @date 2025-07-05
 */
@Service
public class McpWindowsServiceImpl implements IMcpWindowsService 
{
    @Autowired
    private McpWindowsMapper mcpWindowsMapper;

    @Autowired
    private IMcpFormulasService mcpFormulasService;

    @Autowired
    private IMcpMaterialResultsService mcpMaterialResultsService;

    @Autowired
    private IMcpProjectsService mcpProjectsService;

    @Autowired
    private IMcpWindowTypesService  mcpWindowTypesService;

    @Autowired
    private IMcpCompaniesService mcpCompaniesService;


    /**
     * 查询门窗详细信息
     * 
     * @param id 门窗详细信息主键
     * @return 门窗详细信息
     */
    @Override
    public McpWindows selectMcpWindowsById(Long id)
    {
        return mcpWindowsMapper.selectMcpWindowsById(id);
    }
    /**
     * 查询门窗详细信息
     *
     * @param ids 门窗详细信息主键
     * @return 门窗详细信息
     */
    @Override
    public List<McpWindows> selectMcpWindowsByIds(Long[] ids)
    {
        return mcpWindowsMapper.selectMcpWindowsByIds(ids);
    }

    /**
     * 查询门窗详细信息列表
     * 
     * @param mcpWindows 门窗详细信息
     * @return 门窗详细信息
     */
    @Override
    @DataScope(userAlias = "u")
    public List<McpWindows> selectMcpWindowsList(McpWindows mcpWindows)
    {
        return mcpWindowsMapper.selectMcpWindowsList(mcpWindows);
    }

    @Override
    public List<McpWindows> selectMcpWindowsListByProjectIds(Long[] ids) {
        return  mcpWindowsMapper.selectMcpWindowsListByProjectIds(ids);
    }

    /**
     * 新增门窗详细信息
     * 
     * @param mcpWindows 门窗详细信息
     * @return 结果
     */
    @Transactional
    @Override
    public int insertMcpWindows(McpWindows mcpWindows)
    {
        if(mcpWindows.getProjectId() == null) {
            McpProjects mcpProjects = mcpProjectsService.selectMcpProjectsById(mcpWindows.getProjectId());
            if (mcpProjects == null){
                throw new ServiceException("项目已被删除，请重新选择项目");
            }
        }
        if (mcpWindows.getTypeId() == null) {
            McpWindowTypes mcpWindowTypes = mcpWindowTypesService.selectMcpWindowTypesById(mcpWindows.getTypeId());
            if (mcpWindowTypes == null){
                throw new ServiceException("门窗类型已被删除，请重新选择门窗类型");
            }
        }
        mcpWindows.setCreateTime(DateUtils.getNowDate());
        mcpWindows.setCreateBy(SecurityUtils.getUsername());
        mcpWindows.setCreateById(SecurityUtils.getUserId());
        int rows = mcpWindowsMapper.insertMcpWindows(mcpWindows);
        insertMcpVariableValue(mcpWindows);
        return rows;
    }

    /**
     * 修改门窗详细信息
     * 
     * @param mcpWindows 门窗详细信息
     * @return 结果
     */
    @Transactional
    @Override
    public int updateMcpWindows(McpWindows mcpWindows)
    {
        if(mcpWindows.getProjectId() == null) {
            McpProjects mcpProjects = mcpProjectsService.selectMcpProjectsById(mcpWindows.getProjectId());
            if (mcpProjects == null){
                throw new ServiceException("项目被删除，请重新选择项目");
            }
        }
        if (mcpWindows.getTypeId() == null) {
            McpWindowTypes mcpWindowTypes = mcpWindowTypesService.selectMcpWindowTypesById(mcpWindows.getTypeId());
            if (mcpWindowTypes == null){
                throw new ServiceException("门窗类型被删除，请重新选择门窗类型");
            }
        }
        mcpWindows.setUpdateTime(DateUtils.getNowDate());
        mcpWindows.setUpdateBy(SecurityUtils.getUsername());
        mcpWindows.setUpdateById(SecurityUtils.getUserId());
        mcpWindowsMapper.deleteMcpVariableValueByWindowsId(mcpWindows.getId());
        insertMcpVariableValue(mcpWindows);
        return mcpWindowsMapper.updateMcpWindows(mcpWindows);
    }

    /**
     * 批量删除门窗详细信息
     * 
     * @param ids 需要删除的门窗详细信息主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteMcpWindowsByIds(Long[] ids)
    {
        // 删除门窗用料公式值
        mcpWindowsMapper.deleteMcpVariableValueByWindowsIds(ids);
        // 删除门窗用料结果
        mcpMaterialResultsService.deleteMcpMaterialResultsByWindowIds(ids);

        return mcpWindowsMapper.deleteMcpWindowsByIds(ids);
    }

    /**
     * 删除门窗详细信息信息
     * 
     * @param id 门窗详细信息主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteMcpWindowsById(Long id)
    {
        mcpWindowsMapper.deleteMcpVariableValueByWindowsId(id);
        return mcpWindowsMapper.deleteMcpWindowsById(id);
    }
    @Transactional
    @Override
    public int calculateMcpWindowsById(Long id) {
        // 根据工程门窗查询门窗类型
        McpWindows mcpWindows = mcpWindowsMapper.selectMcpWindowsById(id);
        if (mcpWindows == null) {
            throw new ServiceException("门窗不存在");
        }
        McpProjects mcpProjects = mcpProjectsService.selectMcpProjectsById(mcpWindows.getProjectId());
        if (mcpProjects == null) {
            throw new ServiceException("项目不存在");
        }
        McpCompanies mcpCompanies = mcpCompaniesService.selectMcpCompaniesById(mcpWindows.getCompanyId());
        if (mcpCompanies == null) {
            throw new ServiceException("公司不存在");
        }
        McpWindowTypes mcpWindowTypes = mcpWindowTypesService.selectMcpWindowTypesById(mcpWindows.getTypeId());
        if (mcpWindowTypes == null) {
            throw new ServiceException("门窗类型不存在");
        }

        // 根据工程门窗查询门窗变量值
        List<McpVariableValue> mcpVariableValueList = mcpWindows.getMcpVariableValueList();
        // 门窗类型查询公式
        McpFormulas searchFormulas = new McpFormulas();
        searchFormulas.setTypeId(mcpWindows.getTypeId());
        List<McpFormulas> mcpFormulas = mcpFormulasService.selectMcpFormulasList(searchFormulas);
        mcpMaterialResultsService.deleteMcpMaterialResultsByWindowId( id);
        // 根据公式计算
        for (int i = 0; i < mcpFormulas.size(); i++) {
            McpMaterialResults mcpMaterialResults = new McpMaterialResults();
            McpFormulas mcpFormulas1 = mcpFormulas.get(i);
            String formulaContent = mcpFormulas1.getFormulaContent();
            if (StringUtils.isNotEmpty(formulaContent)) {
                Expression expression = new Expression(formulaContent);
                // 添加变量
                for (int i1 = 0; i1 < mcpVariableValueList.size(); i1++) {
                    McpVariableValue mcpVariableValue = mcpVariableValueList.get(i1);
                    expression.with(mcpVariableValue.getVariableName(), mcpVariableValue.getValue());
                }
                try {
                    String stringValue = expression.evaluate().getStringValue();
                    mcpMaterialResults.setMaterialLength(new BigDecimal(stringValue));
                } catch (ParseException | EvaluationException e) {
                    throw new RuntimeException(e);
                }
            }
            mcpMaterialResults.setMaterialName(mcpFormulas1.getMaterialName());
            mcpMaterialResults.setMaterialCount(mcpFormulas1.getMaterialCount()*mcpWindows.getQuantity());
            mcpMaterialResults.setMaterialWeightPerMeter(mcpFormulas1.getMaterialWeightPerMeter());
            mcpMaterialResults.setWindowId(id);
            // 结果插入mcp_material_results中
            mcpMaterialResultsService.insertMcpMaterialResults(mcpMaterialResults);
        }

        return 1;
    }

    /**
     * 新增门窗用料公式值信息
     * 
     * @param mcpWindows 门窗详细信息对象
     */
    public void insertMcpVariableValue(McpWindows mcpWindows)
    {
        List<McpVariableValue> mcpVariableValueList = mcpWindows.getMcpVariableValueList();
        Long id = mcpWindows.getId();
        if (StringUtils.isNotNull(mcpVariableValueList))
        {
            List<McpVariableValue> list = new ArrayList<McpVariableValue>();
            for (McpVariableValue mcpVariableValue : mcpVariableValueList)
            {
                mcpVariableValue.setWindowsId(id);
                mcpVariableValue.setCreateTime(DateUtils.getNowDate());
                mcpVariableValue.setCreateBy(SecurityUtils.getUsername());
                mcpVariableValue.setCreateById(SecurityUtils.getUserId());
                list.add(mcpVariableValue);
            }
            if (list.size() > 0)
            {
                mcpWindowsMapper.batchMcpVariableValue(list);
            }
        }
    }
    /**
     * 查询门窗用料公式值
     *
     * @param id 门窗详细信息主键
     * @return 门窗用料公式值
     */
    @Override
    public List<McpVariableValue> selectMcpVariableValueList(Long id){

        return mcpWindowsMapper.selectMcpVariableValueList(id);
    }
}
